home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-05-03 | 46.0 KB | 2,261 lines |
- Newsgroups: comp.sources.unix
- From: pmiller@bmr.gov.au (Peter Miller)
- Subject: v26i219: cook-1.4 - a file construction tool (like "make"), Part11/11
- Sender: unix-sources-moderator@efficacy.home.vix.com
- Approved: WhoAmI@efficacy.home.vix.com
-
- Submitted-By: pmiller@bmr.gov.au (Peter Miller)
- Posting-Number: Volume 26, Issue 219
- Archive-Name: cook-1.4/part11
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 11 (of 11)."
- # Contents: cook/builtin.c
- # Wrapped by vixie@efficacy.home.vix.com on Tue May 4 01:36:43 1993
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'cook/builtin.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'cook/builtin.c'\"
- else
- echo shar: Extracting \"'cook/builtin.c'\" \(43130 characters\)
- sed "s/^X//" >'cook/builtin.c' <<'END_OF_FILE'
- X/*
- X * cook - file construction tool
- X * Copyright (C) 1991, 1992, 1993 Peter Miller.
- X * All rights reserved.
- X *
- X * This program is free software; you can redistribute it and/or modify
- X * it under the terms of the GNU General Public License as published by
- X * the Free Software Foundation; either version 2 of the License, or
- X * (at your option) any later version.
- X *
- X * This program is distributed in the hope that it will be useful,
- X * but WITHOUT ANY WARRANTY; without even the implied warranty of
- X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- X * GNU General Public License for more details.
- X *
- X * You should have received a copy of the GNU General Public License
- X * along with this program; if not, write to the Free Software
- X * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- X *
- X * MANIFEST: functions to implement the builtin functions
- X *
- X * The builtin function all append their results to the supplied
- X * `result' word list. The first word of the `args' word list
- X * is the name of the function.
- X *
- X * all of the functions return 0 in success, or -1 on error.
- X *
- X * Only a limited set of this are candidates for builtin functions,
- X * these are
- X * - string manipulation [dirname, stringset, ect ]
- X * - environment manipulation [getenv(3), etc]
- X * - stat(3) related functions [exists, mtime, pathname, etc]
- X * - launching OS commands [execute, collect]
- X * The above list is though to be exhaustive.
- X *
- X * This explicitly and forever excluded from being a builtin function
- X * is anything which known or understands the format of some secific
- X * class of files.
- X *
- X * Access to stdio(3) has been thought of, and explicitly avoided.
- X * Mostly because a specialist program used through [collect]
- X * will almost always be far faster.
- X */
- X
- X#include <stddef.h>
- X#include <stdlib.h>
- X#include <stdio.h>
- X#include <string.h>
- X#include <time.h>
- X#include <errno.h>
- X#include <sys/utsname.h>
- X
- X#include <builtin.h>
- X#include <cook.h>
- X#include <error.h>
- X#include <expr.h>
- X#include <glob.h>
- X#include <id.h>
- X#include <main.h>
- X#include <match.h>
- X#include <mem.h>
- X#include <option.h>
- X#include <os.h>
- X#include <word.h>
- X
- X
- Xtypedef struct func_ty func_ty;
- Xstruct func_ty
- X{
- X char *f_name;
- X bifp f_code;
- X};
- X
- X
- X/*
- X * NAME
- X * func_if - conditional evaluation
- X *
- X * SYNOPSIS
- X * int func_if(wlist *result, wlist *args);
- X *
- X * DESCRIPTION
- X * Defined is a built-in function of if, described as follows:
- X * This function requires one or more arguments.
- X * The condition before the 'then' keyword is evaluated,
- X * if true, the words between the 'then' and the 'else' are the result,
- X * otherwise the words between the 'else' and the end are the value.
- X * The else is optional.
- X *
- X * RETURNS
- X * Appropriate things, see above.
- X *
- X * CAVEAT
- X * The returned result is in dynamic memory.
- X * It is the responsibility of the caller to dispose of
- X * the result when it is finished, with a wl_free() call.
- X *
- X * 'then' and 'else' cant be escaped, sorry.
- X */
- X
- Xstatic int func_if _((wlist *, wlist *));
- X
- Xstatic int
- Xfunc_if(result, args)
- X wlist *result;
- X wlist *args;
- X{
- X int j;
- X int cond;
- X static string_ty *str_then;
- X static string_ty *str_else;
- X
- X assert(result);
- X assert(args);
- X assert(args->wl_nwords);
- X if (args->wl_nwords < 2)
- X {
- X expr_error
- X (
- X "%s: requires one or more arguments",
- X args->wl_word[0]->str_text
- X );
- X return -1;
- X }
- X cond = 0;
- X if (!str_then)
- X str_then = str_from_c("then");
- X if (!str_else)
- X str_else = str_from_c("else");
- X for
- X (
- X j = 1;
- X j < args->wl_nwords && !str_equal(str_then, args->wl_word[j]);
- X j++
- X )
- X cond |= str_bool(args->wl_word[j]);
- X if (j >= args->wl_nwords)
- X {
- X expr_error("%s: no 'then' word", args->wl_word[0]->str_text);
- X return -1;
- X }
- X j++;
- X if (cond)
- X {
- X while
- X (
- X j < args->wl_nwords
- X &&
- X !str_equal(str_else, args->wl_word[j])
- X )
- X {
- X wl_append(result, args->wl_word[j]);
- X j++;
- X }
- X }
- X else
- X {
- X while
- X (
- X j < args->wl_nwords
- X &&
- X !str_equal(str_else, args->wl_word[j])
- X )
- X j++;
- X if (j < args->wl_nwords)
- X {
- X j++;
- X while (j < args->wl_nwords)
- X {
- X wl_append(result, args->wl_word[j]);
- X ++j;
- X }
- X }
- X }
- X return 0;
- X}
- X
- X
- X/*
- X * NAME
- X * func_upcase - upcase strings
- X *
- X * SYNOPSIS
- X * int func_upcase(wlist *result, wlist *args);
- X *
- X * DESCRIPTION
- X * Defined is a built-in function of cook, described as follows:
- X * This function requires one or more arguments,
- X * which will bu upcased.
- X *
- X * RETURNS
- X * It returns the arguments upcased.
- X *
- X * CAVEAT
- X * The returned result is in dynamic memory.
- X * It is the responsibility of the caller to dispose of
- X * the result when it is finished, with a wl_free() call.
- X */
- X
- Xstatic int func_upcase _((wlist *, wlist *));
- X
- Xstatic int
- Xfunc_upcase(result, args)
- X wlist *result;
- X wlist *args;
- X{
- X int j;
- X
- X assert(result);
- X assert(args);
- X assert(args->wl_nwords);
- X if (args->wl_nwords < 2)
- X {
- X expr_error
- X (
- X "%s: requires one or more arguments",
- X args->wl_word[0]->str_text
- X );
- X return -1;
- X }
- X for (j = 1; j < args->wl_nwords; j++)
- X {
- X string_ty *s;
- X
- X s = str_upcase(args->wl_word[j]);
- X wl_append(result, s);
- X str_free(s);
- X }
- X return 0;
- X}
- X
- X
- X/*
- X * NAME
- X * func_downcase - downcase strings
- X *
- X * SYNOPSIS
- X * int func_downcase(wlist *result, wlist *args);
- X *
- X * DESCRIPTION
- X * Defined is a built-in function of cook, described as follows:
- X * This function requires one or more arguments,
- X * which will bu downcased.
- X *
- X * RETURNS
- X * It returns the arguments downcased.
- X *
- X * CAVEAT
- X * The returned result is in dynamic memory.
- X * It is the responsibility of the caller to dispose of
- X * the result when it is finished, with a wl_free() call.
- X */
- X
- Xstatic int func_downcase _((wlist *, wlist *));
- X
- Xstatic int
- Xfunc_downcase(result, args)
- X wlist *result;
- X wlist *args;
- X{
- X int j;
- X
- X assert(result);
- X assert(args);
- X assert(args->wl_nwords);
- X if (args->wl_nwords < 2)
- X {
- X expr_error
- X (
- X "%s: requires one or more arguments",
- X args->wl_word[0]->str_text
- X );
- X return -1;
- X }
- X for (j = 1; j < args->wl_nwords; j++)
- X {
- X string_ty *s;
- X
- X s = str_downcase(args->wl_word[j]);
- X wl_append(result, s);
- X str_free(s);
- X }
- X return 0;
- X}
- X
- X
- X/*
- X * NAME
- X * func_dir - dir part
- X *
- X * SYNOPSIS
- X * int func_dir(wlist *result, wlist *args);
- X *
- X * DESCRIPTION
- X * "dir" is a built-in function of cook, described as follows:
- X * This function requires one or more arguments,
- X * the name of a files of which to get the dir parts.
- X *
- X * RETURNS
- X * It returns a string containing the directory parts
- X * of the named files.
- X *
- X * CAVEAT
- X * The returned result is in dynamic memory.
- X * It is the responsibility of the caller to dispose of
- X * the result when it is finished, with a wl_free() call.
- X */
- X
- Xstatic int func_dir _((wlist *, wlist *));
- X
- Xstatic int
- Xfunc_dir(result, args)
- X wlist *result;
- X wlist *args;
- X{
- X int j;
- X
- X assert(result);
- X assert(args);
- X assert(args->wl_nwords);
- X if (args->wl_nwords < 2)
- X {
- X expr_error
- X (
- X "%s: requires one or more arguments",
- X args->wl_word[0]->str_text
- X );
- X return -1;
- X }
- X for (j = 1; j < args->wl_nwords; j++)
- X {
- X string_ty *s;
- X
- X s = os_dirname(args->wl_word[j]);
- X if (!s)
- X return -1;
- X wl_append(result, s);
- X str_free(s);
- X }
- X return 0;
- X}
- X
- X
- X/*
- X * NAME
- X * func_entryname - entryname part
- X *
- X * SYNOPSIS
- X * int func_entryname(wlist *result, wlist *args);
- X *
- X * DESCRIPTION
- X * Defined is a built-in function of cook, described as follows:
- X * This function requires one or more arguments,
- X * the name of a files of which to get the entryname parts.
- X *
- X * RETURNS
- X * It returns a string containing the entryname parts
- X * of the named files.
- X *
- X * CAVEAT
- X * The returned result is in dynamic memory.
- X * It is the responsibility of the caller to dispose of
- X * the result when it is finished, with a wl_free() call.
- X */
- X
- Xstatic int func_entryname _((wlist *, wlist *));
- X
- Xstatic int
- Xfunc_entryname(result, args)
- X wlist *result;
- X wlist *args;
- X{
- X int j;
- X
- X assert(result);
- X assert(args);
- X assert(args->wl_nwords);
- X if (args->wl_nwords < 2)
- X {
- X expr_error
- X (
- X "%s: requires one or more arguments",
- X args->wl_word[0]->str_text
- X );
- X return -1;
- X }
- X for (j = 1; j < args->wl_nwords; j++)
- X {
- X string_ty *s;
- X
- X s = os_entryname(args->wl_word[j]);
- X if (!s)
- X return -1;
- X wl_append(result, s);
- X str_free(s);
- X }
- X return 0;
- X}
- X
- X
- X/*
- X * NAME
- X * func_pathname - pathname part
- X *
- X * SYNOPSIS
- X * int func_pathname(wlist *result, wlist *args);
- X *
- X * DESCRIPTION
- X * Defined is a built-in function of cook, described as follows:
- X * This function requires one or more arguments,
- X * the name of a files of which to get the pathname parts.
- X *
- X * RETURNS
- X * It returns a string containing the pathname parts
- X * of the named files.
- X *
- X * CAVEAT
- X * The returned result is in dynamic memory.
- X * It is the responsibility of the caller to dispose of
- X * the result when it is finished, with a wl_free() call.
- X */
- X
- Xstatic int func_pathname _((wlist *, wlist *));
- X
- Xstatic int
- Xfunc_pathname(result, args)
- X wlist *result;
- X wlist *args;
- X{
- X int j;
- X
- X assert(result);
- X assert(args);
- X assert(args->wl_nwords);
- X if (args->wl_nwords < 2)
- X {
- X expr_error
- X (
- X "%s: requires one or more arguments",
- X args->wl_word[0]->str_text
- X );
- X return -1;
- X }
- X for (j = 1; j < args->wl_nwords; j++)
- X {
- X string_ty *s;
- X
- X s = os_pathname(args->wl_word[j]);
- X if (!s)
- X return -1;
- X wl_append(result, s);
- X str_free(s);
- X }
- X return 0;
- X}
- X
- X
- X/*
- X * NAME
- X * func_mtime - file last modified time
- X *
- X * SYNOPSIS
- X * int func_mtime(wlist *result, wlist *args);
- X *
- X * DESCRIPTION
- X * Defined is a built-in function of cook, described as follows:
- X * This function requires a single argument,
- X * the name of a file of which to get the last modified time.
- X *
- X * RETURNS
- X * It returns a string containing the last modified time
- X * (suitable for comparing with others) of the named file,
- X * and "" (false) if the files does not exist
- X *
- X * CAVEAT
- X * The returned result is in dynamic memory.
- X * It is the responsibility of the caller to dispose of
- X * the result when it is finished, with a wl_free() call.
- X */
- X
- Xstatic int func_mtime _((wlist *, wlist *));
- X
- Xstatic int
- Xfunc_mtime(result, args)
- X wlist *result;
- X wlist *args;
- X{
- X int j;
- X
- X assert(result);
- X assert(args);
- X assert(args->wl_nwords);
- X if (args->wl_nwords < 2)
- X {
- X expr_error
- X (
- X "%s: requires one or more arguments",
- X args->wl_word[0]->str_text
- X );
- X return -1;
- X }
- X for (j = 1; j < args->wl_nwords; j++)
- X {
- X time_t mtime;
- X
- X mtime = os_mtime(args->wl_word[j]);
- X if (mtime < 0)
- X return -1;
- X if (mtime == 0)
- X wl_append(result, str_false);
- X else
- X {
- X struct tm *tm;
- X string_ty *s;
- X
- X tm = localtime(&mtime);
- X s =
- X str_format
- X (
- X "%02d%02d%02d%02d%02d%02d",
- X tm->tm_year,
- X tm->tm_mon+1,
- X tm->tm_mday,
- X tm->tm_hour,
- X tm->tm_min,
- X tm->tm_sec
- X );
- X wl_append(result, s);
- X str_free(s);
- X }
- X }
- X return 0;
- X}
- X
- X
- X/*
- X * NAME
- X * func_prepost - add prefix and suffix
- X *
- X * SYNOPSIS
- X * int func_prepost(wlist *result, wlist *args);
- X *
- X * DESCRIPTION
- X * Prepost is a built-in function of cook, described as follows:
- X * This function must have at least two arguments.
- X * The first argument is a prefix and the second argument is a suffix.
- X *
- X * RETURNS
- X * The resulting word list is the third and later arguments each given
- X * the prefix and suffix as defined by the first and second arguments.
- X *
- X * CAVEAT
- X * The returned result is in dynamic memory.
- X * It is the responsibility of the caller to dispose of
- X * the result when it is finished, with a wl_free() call.
- X */
- X
- Xstatic int func_prepost _((wlist *, wlist *));
- X
- Xstatic int
- Xfunc_prepost(result, args)
- X wlist *result;
- X wlist *args;
- X{
- X int j;
- X
- X assert(result);
- X assert(args);
- X assert(args->wl_nwords);
- X if (args->wl_nwords < 3)
- X {
- X expr_error
- X (
- X "%s: requires at least two arguments",
- X args->wl_word[0]->str_text
- X );
- X return -1;
- X }
- X for (j = 3; j < args->wl_nwords; j++)
- X {
- X string_ty *s;
- X
- X s =
- X str_cat_three
- X (
- X args->wl_word[1],
- X args->wl_word[j],
- X args->wl_word[2]
- X );
- X wl_append(result, s);
- X str_free(s);
- X }
- X return 0;
- X}
- X
- X
- X/*
- X * NAME
- X * func_defined - is a variable defined
- X *
- X * SYNOPSIS
- X * int func_defined(wlist *result, wlist *args);
- X *
- X * DESCRIPTION
- X * Defined is a built-in function of cook, described as follows:
- X * This function requires a single argument,
- X * the name of a variable to be tested for existence.
- X *
- X * RETURNS
- X * It returns "1" (true) if the named variable is defined
- X * and "" (false) if it is not.
- X *
- X * CAVEAT
- X * The returned result is in dynamic memory.
- X * It is the responsibility of the caller to dispose of
- X * the result when it is finished, with a wl_free() call.
- X */
- X
- Xstatic int func_defined _((wlist *, wlist *));
- X
- Xstatic int
- Xfunc_defined(result, args)
- X wlist *result;
- X wlist *args;
- X{
- X int j;
- X
- X assert(result);
- X assert(args);
- X assert(args->wl_nwords);
- X if (args->wl_nwords < 2)
- X {
- X expr_error
- X (
- X "%s: requires one or more arguments",
- X args->wl_word[0]->str_text
- X );
- X return -1;
- X }
- X for (j = 1; j < args->wl_nwords; j++)
- X {
- X wlist value;
- X
- X if (id_search(args->wl_word[j], ID_CLASS_VARIABLE, &value))
- X {
- X wl_free(&value);
- X wl_append(result, str_true);
- X }
- X else
- X wl_append(result, str_false);
- X }
- X return 0;
- X}
- X
- X
- X/*
- X * NAME
- X * func_not - logical negation
- X *
- X * SYNOPSIS
- X * int func_not(wlist *result, wlist *args);
- X *
- X * DESCRIPTION
- X * Not is a built-in function of cook, described as follows:
- X * This function requires zero or more arguments,
- X * the value to be logically negated.
- X *
- X * RETURNS
- X * It returns "1" (true) if all of the arguments are "" (false), or there
- X * are no arguments; and returns "" (false) otherwise.
- X *
- X * CAVEAT
- X * The returned result is in dynamic memory.
- X * It is the responsibility of the caller to dispose of
- X * the result when it is finished, with a wl_free() call.
- X */
- X
- Xstatic int func_not _((wlist *, wlist *));
- X
- Xstatic int
- Xfunc_not(result, args)
- X wlist *result;
- X wlist *args;
- X{
- X int j;
- X
- X assert(result);
- X assert(args);
- X assert(args->wl_nwords);
- X for (j = 1; j < args->wl_nwords; j++)
- X {
- X if (str_bool(args->wl_word[j]))
- X {
- X wl_append(result, str_false);
- X return 0;
- X }
- X }
- X wl_append(result, str_true);
- X return 0;
- X}
- X
- X
- X/*
- X * NAME
- X * func_and - logical conjunction
- X *
- X * SYNOPSIS
- X * int func_and(wlist *result, wlist *args);
- X *
- X * DESCRIPTION
- X * And is a built-in function of cook, described as follows:
- X * This function requires at least two arguments,
- X * upon which it forms a logical conjunction.
- X *
- X * RETURNS
- X * The value returned is "1" (true) if none of the arguments
- X * are "" (false), otherwise "" (false) is returned.
- X *
- X * CAVEAT
- X * The returned result is in dynamic memory.
- X * It is the responsibility of the caller to dispose of
- X * the result when it is finished, with a wl_free() call.
- X */
- X
- Xstatic int func_and _((wlist *, wlist *));
- X
- Xstatic int
- Xfunc_and(result, args)
- X wlist *result;
- X wlist *args;
- X{
- X int j;
- X
- X assert(result);
- X assert(args);
- X assert(args->wl_nwords);
- X if (args->wl_nwords < 3)
- X {
- X expr_error
- X (
- X "%s: requires at least two arguments",
- X args->wl_word[0]->str_text
- X );
- X return -1;
- X }
- X for (j = 1; j < args->wl_nwords; j++)
- X {
- X if (!str_bool(args->wl_word[j]))
- X {
- X wl_append(result, str_false);
- X return 0;
- X }
- X }
- X wl_append(result, str_true);
- X return 0;
- X}
- X
- X
- X/*
- X * NAME
- X * func_or - logical disjunction
- X *
- X * SYNOPSIS
- X * int func_or(wlist *result, wlist *args);
- X *
- X * DESCRIPTION
- X * Or is a built-in function of cook, described as follows:
- X * This function requires at least two arguments,
- X * upon which it forms a logical disjunction.
- X *
- X * RETURNS
- X * The value returned is "1" (true) if any one of the arguments is
- X * not "" (false), otherwise "" (false) is returned.
- X *
- X * CAVEAT
- X * The returned result is in dynamic memory.
- X * It is the responsibility of the caller to dispose of
- X * the result when it is finished, with a wl_free() call.
- X */
- X
- Xstatic int func_or _((wlist *, wlist *));
- X
- Xstatic int
- Xfunc_or(result, args)
- X wlist *result;
- X wlist *args;
- X{
- X int j;
- X
- X assert(result);
- X assert(args);
- X assert(args->wl_nwords);
- X if (args->wl_nwords < 3)
- X {
- X expr_error
- X (
- X "%s: requires at least two arguments",
- X args->wl_word[0]->str_text
- X );
- X return -1;
- X }
- X for (j = 1; j < args->wl_nwords; j++)
- X {
- X if (str_bool(args->wl_word[j]))
- X {
- X wl_append(result, str_true);
- X return 0;
- X }
- X }
- X wl_append(result, str_false);
- X return 0;
- X}
- X
- X
- X/*
- X * NAME
- X * func_exec - execute a command
- X *
- X * SYNOPSIS
- X * int func_exec(wlist *result, wlist *args);
- X *
- X * DESCRIPTION
- X * Exec is a built-in function of cook, described as follows:
- X * This function requires at least one argument, and
- X * executes the command given by the arguments.
- X *
- X * RETURNS
- X * If the executed command returns an error code the resulting value
- X * is "" (false), otherwise it is "1" (true).
- X *
- X * CAVEAT
- X * The returned result is in dynamic memory.
- X * It is the responsibility of the caller to dispose of
- X * the result when it is finished, with a wl_free() call.
- X */
- X
- Xstatic int func_exec _((wlist *, wlist *));
- X
- Xstatic int
- Xfunc_exec(result, args)
- X wlist *result;
- X wlist *args;
- X{
- X wlist wl;
- X int j;
- X string_ty *s;
- X
- X assert(result);
- X assert(args);
- X assert(args->wl_nwords);
- X if (args->wl_nwords < 2)
- X {
- X expr_error
- X (
- X "%s: requires at least one argument",
- X args->wl_word[0]->str_text
- X );
- X return -1;
- X }
- X wl_zero(&wl);
- X for (j = 1; j < args->wl_nwords; j++)
- X wl_append(&wl, args->wl_word[j]);
- X j = os_execute(&wl, (string_ty *)0);
- X wl_free(&wl);
- X if (j < 0)
- X return -1;
- X s = (j ? str_false : str_true);
- X wl_append(result, s);
- X return 0;
- X}
- X
- X
- X/*
- X * NAME
- X * func_match - wildcard mapping
- X *
- X * SYNOPSIS
- X * int func_match(wlist *result, wlist *args);
- X *
- X * DESCRIPTION
- X * Fromto is a built-in function of cook, described as follows:
- X * This function requires at least two arguments.
- X * Fromto gives the user access to the wildcard transformations
- X * available to cook.
- X * The first argument is the "from" form,
- X * the second argument is the "to" form.
- X *
- X * RETURNS
- X * All other arguments are mapped from one to the other.
- X *
- X * CAVEAT
- X * The returned result is in dynamic memory.
- X * It is the responsibility of the caller to dispose of
- X * the result when it is finished, with a wl_free() call.
- X */
- X
- Xstatic int func_match _((wlist *, wlist *));
- X
- Xstatic int
- Xfunc_match(result, args)
- X wlist *result;
- X wlist *args;
- X{
- X int j;
- X match_ty *field;
- X
- X assert(result);
- X assert(args);
- X assert(args->wl_nwords);
- X if (args->wl_nwords < 2)
- X {
- X expr_error
- X (
- X "%s: requires one or more arguments",
- X args->wl_word[0]->str_text
- X );
- X return -1;
- X }
- X for (j = 2; j < args->wl_nwords; j++)
- X {
- X field = match(args->wl_word[1], args->wl_word[j]);
- X if (field)
- X {
- X wl_append(result, str_true);
- X match_free(field);
- X }
- X else
- X wl_append(result, str_false);
- X }
- X return 0;
- X}
- X
- X
- X/*
- X * NAME
- X * func_match - wildcard mapping
- X *
- X * SYNOPSIS
- X * int func_match(wlist *result, wlist *args);
- X *
- X * DESCRIPTION
- X * Fromto is a built-in function of cook, described as follows:
- X * This function requires at least two arguments.
- X * Fromto gives the user access to the wildcard transformations
- X * available to cook.
- X * The first argument is the "from" form,
- X * the second argument is the "to" form.
- X *
- X * RETURNS
- X * All other arguments are mapped from one to the other.
- X *
- X * CAVEAT
- X * The returned result is in dynamic memory.
- X * It is the responsibility of the caller to dispose of
- X * the result when it is finished, with a wl_free() call.
- X */
- X
- Xstatic int func_match_mask _((wlist *, wlist *));
- X
- Xstatic int
- Xfunc_match_mask(result, args)
- X wlist *result;
- X wlist *args;
- X{
- X int j;
- X match_ty *field;
- X
- X assert(result);
- X assert(args);
- X assert(args->wl_nwords);
- X if (args->wl_nwords < 2)
- X {
- X expr_error
- X (
- X "%s: requires one or more arguments",
- X args->wl_word[0]->str_text
- X );
- X return -1;
- X }
- X for (j = 2; j < args->wl_nwords; j++)
- X {
- X field = match(args->wl_word[1], args->wl_word[j]);
- X if (field)
- X {
- X wl_append(result, args->wl_word[j]);
- X match_free(field);
- X }
- X }
- X return 0;
- X}
- X
- X
- X/*
- X * NAME
- X * func_fromto - wildcard mapping
- X *
- X * SYNOPSIS
- X * int func_fromto(wlist *result, wlist *args);
- X *
- X * DESCRIPTION
- X * Fromto is a built-in function of cook, described as follows:
- X * This function requires at least two arguments.
- X * Fromto gives the user access to the wildcard transformations
- X * available to cook.
- X * The first argument is the "from" form,
- X * the second argument is the "to" form.
- X *
- X * RETURNS
- X * All other arguments are mapped from one to the other.
- X *
- X * CAVEAT
- X * The returned result is in dynamic memory.
- X * It is the responsibility of the caller to dispose of
- X * the result when it is finished, with a wl_free() call.
- X */
- X
- Xstatic int func_fromto _((wlist *, wlist *));
- X
- Xstatic int
- Xfunc_fromto(result, args)
- X wlist *result;
- X wlist *args;
- X{
- X int j;
- X match_ty *field;
- X
- X assert(result);
- X assert(args);
- X assert(args->wl_nwords);
- X if (args->wl_nwords < 3)
- X {
- X expr_error
- X (
- X "%s: requires at least two arguments",
- X args->wl_word[0]->str_text
- X );
- X return -1;
- X }
- X for (j = 3; j < args->wl_nwords; j++)
- X {
- X field = match(args->wl_word[1], args->wl_word[j]);
- X if (field)
- X {
- X string_ty *s;
- X
- X s = reconstruct(args->wl_word[2], field);
- X wl_append(result, s);
- X str_free(s);
- X match_free(field);
- X }
- X else
- X wl_append(result, args->wl_word[j]);
- X }
- X return 0;
- X}
- X
- X
- X/*
- X * NAME
- X * func_head - head of a wordlist
- X *
- X * SYNOPSIS
- X * int func_fromto(wlist *result, wlist *args);
- X *
- X * DESCRIPTION
- X * Head is a built-in function of cook, described as follows:
- X * This function requires zero or more arguments.
- X *
- X * RETURNS
- X * The wordlist returned is empty if there were no arguemnts,
- X * or the first argument if there were arguments.
- X *
- X * CAVEAT
- X * The returned result is in dynamic memory.
- X * It is the responsibility of the caller to dispose of
- X * the result when it is finished, with a wl_free() call.
- X */
- X
- Xstatic int func_head _((wlist *, wlist *));
- X
- Xstatic int
- Xfunc_head(result, args)
- X wlist *result;
- X wlist *args;
- X{
- X assert(result);
- X assert(args);
- X assert(args->wl_nwords);
- X if (args->wl_nwords >= 2)
- X wl_append(result, args->wl_word[1]);
- X return 0;
- X}
- X
- X
- X/*
- X * NAME
- X * func_tail - tail of a wordlist
- X *
- X * SYNOPSIS
- X * int func_tail(wlist *result, wlist *args);
- X *
- X * DESCRIPTION
- X * Tail is a built-in function of cook, described as follows:
- X * This function requires zero or more arguments.
- X *
- X * RETURNS
- X * The word list returned will be empty if
- X * there is less than two arguemnts,
- X * otherwise it will consist of the second and later arguments.
- X *
- X * CAVEAT
- X * The returned result is in dynamic memory.
- X * It is the responsibility of the caller to dispose of
- X * the result when it is finished, with a wl_free() call.
- X */
- X
- Xstatic int func_tail _((wlist *, wlist *));
- X
- Xstatic int
- Xfunc_tail(result, args)
- X wlist *result;
- X wlist *args;
- X{
- X int j;
- X
- X assert(result);
- X assert(args);
- X assert(args->wl_nwords);
- X for (j = 2; j < args->wl_nwords; j++)
- X wl_append(result, args->wl_word[j]);
- X return 0;
- X}
- X
- X
- X/*
- X * NAME
- X * func_catenate - catenate a wordlist
- X *
- X * SYNOPSIS
- X * int func_catenate(wlist *result, wlist *args);
- X *
- X * DESCRIPTION
- X * Catenate is a built-in function of cook, described as follows:
- X * This function requires zero or more arguments.
- X *
- X * RETURNS
- X * A word list containg zero words if there were no arguments,
- X * or a single word which is the catenation of the arguments.
- X *
- X * CAVEAT
- X * The returned result is in dynamic memory.
- X * It is the responsibility of the caller to dispose of
- X * the result when it is finished, with a wl_free() call.
- X */
- X
- Xstatic int func_catenate _((wlist *, wlist *));
- X
- Xstatic int
- Xfunc_catenate(result, args)
- X wlist *result;
- X wlist *args;
- X{
- X int j;
- X static char *tmp;
- X static size_t tmplen;
- X size_t length;
- X char *pos;
- X string_ty *s;
- X
- X assert(result);
- X assert(args);
- X assert(args->wl_nwords);
- X if (args->wl_nwords < 2)
- X return 0;
- X if (args->wl_nwords == 2)
- X {
- X wl_append(result, args->wl_word[1]);
- X return 0;
- X }
- X
- X length = 0;
- X for (j = 1; j < args->wl_nwords; j++)
- X length += args->wl_word[j]->str_length;
- X if (!tmp)
- X {
- X tmplen = length;
- X if (tmplen < 16)
- X tmplen = 16;
- X tmp = mem_alloc(tmplen);
- X }
- X else
- X {
- X if (tmplen < length)
- X {
- X tmplen = length;
- X mem_change_size(&tmp, tmplen);
- X }
- X }
- X pos = tmp;
- X for (j = 1; j < args->wl_nwords; j++)
- X {
- X s = args->wl_word[j];
- X memcpy(pos, s->str_text, s->str_length);
- X pos += s->str_length;
- X }
- X s = str_n_from_c(tmp, length);
- X wl_append(result, s);
- X str_free(s);
- X return 0;
- X}
- X
- X
- X/*
- X * NAME
- X * func_count - length of a word list
- X *
- X * SYNOPSIS
- X * int func_count(wlist *result, wlist *args);
- X *
- X * DESCRIPTION
- X * Count is a built-in function of cook, described as follows:
- X * This function requires zero or more arguments.
- X *
- X * RETURNS
- X * A word list containg a single word containing the (decimal)
- X * length of the argument list.
- X *
- X * CAVEAT
- X * The returned result is in dynamic memory.
- X * It is the responsibility of the caller to dispose of
- X * the result when it is finished, with a wl_free() call.
- X */
- X
- Xstatic int func_count _((wlist *, wlist *));
- X
- Xstatic int
- Xfunc_count(result, args)
- X wlist *result;
- X wlist *args;
- X{
- X string_ty *s;
- X
- X assert(result);
- X assert(args);
- X assert(args->wl_nwords);
- X s = str_format("%ld", args->wl_nwords - 1);
- X wl_append(result, s);
- X str_free(s);
- X return 0;
- X}
- X
- X
- X/*
- X * NAME
- X * func_in - test for set membership
- X *
- X * SYNOPSIS
- X * int func_in(wlist *result, wlist *args);
- X *
- X * DESCRIPTION
- X * In is a built-in function of cook, described as follows:
- X * This function requires one or more arguments.
- X *
- X * RETURNS
- X * A word list containg a single word: "1" (true) if the first argument
- X * is the same as any of the later ones; "" (false) if not.
- X *
- X * CAVEAT
- X * The returned result is in dynamic memory.
- X * It is the responsibility of the caller to dispose of
- X * the result when it is finished, with a wl_free() call.
- X */
- X
- Xstatic int func_in _((wlist *, wlist *));
- X
- Xstatic int
- Xfunc_in(result, args)
- X wlist *result;
- X wlist *args;
- X{
- X int j;
- X
- X assert(result);
- X assert(args);
- X assert(args->wl_nwords);
- X if (args->wl_nwords < 2)
- X {
- X expr_error
- X (
- X "%s: requires one or more arguments",
- X args->wl_word[0]->str_text
- X );
- X return -1;
- X }
- X for (j = 2; j < args->wl_nwords; j++)
- X {
- X if (str_equal(args->wl_word[1], args->wl_word[j]))
- X {
- X wl_append(result, str_true);
- X return 0;
- X }
- X }
- X wl_append(result, str_false);
- X return 0;
- X}
- X
- X
- X/*
- X * NAME
- X * func_getenv - get environment variables
- X *
- X * SYNOPSIS
- X * int func_getenv(wlist *result, wlist *args);
- X *
- X * DESCRIPTION
- X * Getenv is a built-in function of cook, described as follows:
- X * This function requires one or more arguments.
- X *
- X * RETURNS
- X * A word list containing the values of the environment variables
- X * given as arguments.
- X *
- X * CAVEAT
- X * The returned result is in dynamic memory.
- X * It is the responsibility of the caller to dispose of
- X * the result when it is finished, with a wl_free() call.
- X */
- X
- Xstatic int func_getenv _((wlist *, wlist *));
- X
- Xstatic int
- Xfunc_getenv(result, args)
- X wlist *result;
- X wlist *args;
- X{
- X int j;
- X
- X assert(result);
- X assert(args);
- X assert(args->wl_nwords);
- X for (j = 1; j < args->wl_nwords; ++j)
- X {
- X char *cp;
- X string_ty *s;
- X
- X cp = getenv(args->wl_word[j]->str_text);
- X if (!cp)
- X wl_append(result, str_false);
- X else
- X {
- X s = str_from_c(cp);
- X wl_append(result, s);
- X str_free(s);
- X }
- X }
- X return 0;
- X}
- X
- X
- X/*
- X * NAME
- X * func_find_command - find pathname commands
- X *
- X * SYNOPSIS
- X * int func_find_command(wlist *result, wlist *args);
- X *
- X * DESCRIPTION
- X * Find_command is a built-in function of cook, described as follows:
- X * This function requires one or more arguments.
- X *
- X * RETURNS
- X * A word list containing the expanded pathname of the named commands
- X * given as arguments.
- X *
- X * CAVEAT
- X * The returned result is in dynamic memory.
- X * It is the responsibility of the caller to dispose of
- X * the result when it is finished, with a wl_free() call.
- X */
- X
- Xstatic int func_find_command _((wlist *, wlist *));
- X
- Xstatic int
- Xfunc_find_command(result, args)
- X wlist *result;
- X wlist *args;
- X{
- X int j;
- X string_ty *paths;
- X char *cp;
- X
- X assert(result);
- X assert(args);
- X assert(args->wl_nwords);
- X cp = getenv("PATH");
- X if (!cp || !*cp)
- X {
- X expr_error
- X (
- X "%s: PATH environment variable not set",
- X args->wl_word[0]->str_text
- X );
- X return -1;
- X }
- X paths = str_from_c(cp);
- X for (j = 1; j < args->wl_nwords; ++j)
- X {
- X string_ty *s;
- X string_ty *s2;
- X
- X s = args->wl_word[j];
- X if (strchr(s->str_text, '/'))
- X {
- X if (os_exists(s))
- X {
- X s2 = os_pathname(s);
- X wl_append(result, s2);
- X str_free(s2);
- X }
- X else
- X wl_append(result, str_false);
- X }
- X else
- X {
- X string_ty *f;
- X int n;
- X
- X for (n = 0; ; ++n)
- X {
- X f = str_field(paths, ':', n);
- X if (!f)
- X {
- X wl_append(result, str_false);
- X break;
- X }
- X s2 = str_format("%S/%S", f, s);
- X str_free(f);
- X switch (os_exists(s2))
- X {
- X case -1:
- X str_free(s2);
- X return -1;
- X
- X case 0:
- X str_free(s2);
- X continue;
- X
- X case 1:
- X f = os_pathname(s2);
- X str_free(s2);
- X wl_append(result, f);
- X str_free(f);
- X break;
- X }
- X break;
- X }
- X }
- X }
- X str_free(paths);
- X return 0;
- X}
- X
- X
- X/*
- X * NAME
- X * func_collect - get output of a command
- X *
- X * SYNOPSIS
- X * int func_collect(wlist *result, wlist *args);
- X *
- X * DESCRIPTION
- X * Collect is a built-in function of cook, described as follows:
- X * This function requires one or more arguments.
- X *
- X * RETURNS
- X * A word list containing the values of the output lines of the
- X * program given in the arguments.
- X *
- X * CAVEAT
- X * The returned result is in dynamic memory.
- X * It is the responsibility of the caller to dispose of
- X * the result when it is finished, with a wl_free() call.
- X */
- X
- Xstatic int func_collect _((wlist *, wlist *));
- X
- Xstatic int
- Xfunc_collect(result, args)
- X wlist *result;
- X wlist *args;
- X{
- X FILE *fp;
- X string_ty *s;
- X char *delim;
- X int status;
- X
- X assert(result);
- X assert(args);
- X assert(args->wl_nwords);
- X if (args->wl_nwords < 2)
- X {
- X expr_error
- X (
- X "%s: requires one or more arguments",
- X args->wl_word[0]->str_text
- X );
- X return -1;
- X }
- X s = wl2str(args, 1, 32767);
- X option_set(OPTION_SILENT, OPTION_LEVEL_EXECUTE, 1);
- X option_set(OPTION_ERROK, OPTION_LEVEL_EXECUTE, 0);
- X if (!option_test(OPTION_SILENT))
- X expr_error("%s", s->str_text);
- X fp = popen(s->str_text, "r");
- X str_free(s);
- X if (!fp)
- X {
- X expr_error
- X (
- X "%s: %s",
- X args->wl_word[1]->str_text,
- X strerror(errno)
- X );
- X return -1;
- X }
- X delim = strchr(args->wl_word[0]->str_text, '_') ? "\n" : "\n \t\f";
- X for (;;)
- X {
- X char buffer[1024];
- X char *cp;
- X int c;
- X
- X for (;;)
- X {
- X c = fgetc(fp);
- X if (c == EOF || !strchr(delim, c))
- X break;
- X }
- X if (c == EOF)
- X break;
- X cp = buffer;
- X for (;;)
- X {
- X *cp++ = c;
- X c = fgetc(fp);
- X if (c == EOF || strchr(delim, c))
- X break;
- X }
- X s = str_n_from_c(buffer, cp - buffer);
- X wl_append(result, s);
- X str_free(s);
- X if (c == EOF)
- X break;
- X }
- X if (ferror(fp))
- X {
- X expr_error
- X (
- X "%s: %s",
- X args->wl_word[1]->str_text,
- X strerror(errno)
- X );
- X return -1;
- X }
- X status = pclose(fp);
- X status = exit_status(args->wl_word[0]->str_text, status);
- X if (status && !option_test(OPTION_ERROK))
- X {
- X option_undo_level(OPTION_LEVEL_EXECUTE);
- X return -1;
- X }
- X option_undo_level(OPTION_LEVEL_EXECUTE);
- X return 0;
- X}
- X
- X
- X/*
- X * NAME
- X * func_opsys - describe operating system
- X *
- X * SYNOPSIS
- X * int func_opsys(wlist *result, wlist *args);
- X *
- X * DESCRIPTION
- X * Operating_system is a built-in function of cook, described as follows:
- X * This function must have zero or more arguments.
- X *
- X * RETURNS
- X * The resulting wordlist contains the values of various
- X * attributes of the operating system, as named in the arguments.
- X * If no attributes are named "name" is assumed.
- X *
- X * CAVEAT
- X * The returned result is in dynamic memory.
- X * It is the responsibility of the caller to dispose of
- X * the result when it is finished, with a wl_free() call.
- X */
- X
- Xstatic int func_opsys _((wlist *, wlist *));
- X
- Xstatic int
- Xfunc_opsys(result, args)
- X wlist *result;
- X wlist *args;
- X{
- X int j;
- X static string_ty *name;
- X static string_ty *machine;
- X static struct utsname uts;
- X static char uts_defined;
- X static string_ty *uts_system;
- X static string_ty *uts_node;
- X static string_ty *uts_release;
- X static string_ty *uts_version;
- X
- X if (!uts_defined)
- X {
- X uname(&uts);
- X uts_defined = 1;
- X }
- X if (!uts_system)
- X uts_system = str_from_c("system");
- X if (!uts_node)
- X uts_node = str_from_c("node");
- X if (!uts_release)
- X uts_release = str_from_c("release");
- X if (!uts_version)
- X uts_version = str_from_c("version");
- X if (!machine)
- X machine = str_from_c("machine");
- X if (!name)
- X name = str_from_c("name");
- X assert(result);
- X assert(args);
- X assert(args->wl_nwords);
- X if (args->wl_nwords < 2)
- X wl_append(args, name);
- X for (j = 1; j < args->wl_nwords; j++)
- X {
- X string_ty *x;
- X
- X x = args->wl_word[j];
- X if (str_equal(name, x))
- X {
- X static string_ty *s;
- X if (!s)
- X {
- X#if defined(sun) || defined(__sun__)
- X s = str_from_c("SunOS");
- X#elif defined(unix) || defined(__unix__)
- X s = str_from_c("unix");
- X#else
- X if (!s)
- X fatal("what OS am I on?");
- X#endif /* OSs */
- X }
- X wl_append(result, s);
- X }
- X else if (str_equal(uts_system, x))
- X {
- X static string_ty *s;
- X if (!s)
- X s = str_from_c(uts.sysname);
- X wl_append(result, s);
- X }
- X else if (str_equal(uts_node, x))
- X {
- X static string_ty *s;
- X if (!s)
- X s = str_from_c(uts.nodename);
- X wl_append(result, s);
- X }
- X else if (str_equal(uts_release, x))
- X {
- X static string_ty *s;
- X if (!s)
- X s = str_from_c(uts.release);
- X wl_append(result, s);
- X }
- X else if (str_equal(uts_version, x))
- X {
- X static string_ty *s;
- X if (!s)
- X s = str_from_c(uts.version);
- X wl_append(result, s);
- X }
- X else if (str_equal(machine, x))
- X {
- X static string_ty *s;
- X if (!s)
- X s = str_from_c(uts.machine);
- X wl_append(result, s);
- X }
- X else
- X {
- X expr_error
- X (
- X "%s: unknown \"%s\" attribute",
- X args->wl_word[0]->str_text,
- X x
- X );
- X return -1;
- X }
- X }
- X return 0;
- X}
- X
- X
- X#define STRINGSET_EOLN 1
- X#define STRINGSET_WORD 2
- X#define STRINGSET_MINUS 3
- X#define STRINGSET_STAR 4
- X
- Xstatic wlist stringset_args;
- Xstatic size_t stringset_pos;
- Xstatic int stringset_token;
- Xstatic string_ty *stringset_token_value;
- X
- X
- Xstatic void stringset_lex _((void));
- X
- Xstatic void
- Xstringset_lex()
- X{
- X static string_ty *minus;
- X static string_ty *star;
- X
- X if (!minus)
- X minus = str_from_c("-");
- X if (!star)
- X star = str_from_c("*");
- X if (stringset_pos >= stringset_args.wl_nwords)
- X {
- X stringset_token_value = str_false;
- X stringset_token = STRINGSET_EOLN;
- X return;
- X }
- X stringset_token_value = stringset_args.wl_word[stringset_pos++];
- X if (str_equal(minus, stringset_token_value))
- X {
- X stringset_token = STRINGSET_MINUS;
- X return;
- X }
- X if (str_equal(star, stringset_token_value))
- X {
- X stringset_token = STRINGSET_STAR;
- X return;
- X }
- X stringset_token = STRINGSET_WORD;
- X}
- X
- X
- Xstatic int stringset_three _((wlist *));
- X
- Xstatic int
- Xstringset_three(result)
- X wlist *result;
- X{
- X while (stringset_token == STRINGSET_WORD)
- X {
- X wl_append_unique(result, stringset_token_value);
- X stringset_lex();
- X }
- X return 0;
- X}
- X
- X
- Xstatic int stringset_two _((wlist *));
- X
- Xstatic int
- Xstringset_two(result)
- X wlist *result;
- X{
- X if (stringset_three(result))
- X return -1;
- X while (stringset_token == STRINGSET_STAR)
- X {
- X wlist lhs;
- X wlist rhs;
- X int j;
- X string_ty *s;
- X
- X stringset_lex();
- X wl_zero(&rhs);
- X if (stringset_three(&rhs))
- X return -1;
- X lhs = *result;
- X wl_zero(result);
- X for (j = 0; j < rhs.wl_nwords; ++j)
- X {
- X s = rhs.wl_word[j];
- X if (wl_member(&lhs, s))
- X wl_append_unique(result, s);
- X }
- X wl_free(&lhs);
- X wl_free(&rhs);
- X }
- X return 0;
- X}
- X
- X
- Xstatic int stringset_one _((wlist *));
- X
- Xstatic int
- Xstringset_one(result)
- X wlist *result;
- X{
- X if (stringset_two(result))
- X return -1;
- X while (stringset_token == STRINGSET_MINUS)
- X {
- X wlist wl;
- X int j;
- X
- X wl_zero(&wl);
- X stringset_lex();
- X if (stringset_two(&wl))
- X return -1;
- X for (j = 0; j < wl.wl_nwords; ++j)
- X wl_delete(result, wl.wl_word[j]);
- X wl_free(&wl);
- X }
- X return 0;
- X}
- X
- X
- Xstatic int stringset _((wlist *, wlist *));
- X
- Xstatic int
- Xstringset(result, args)
- X wlist *result;
- X wlist *args;
- X{
- X wlist wl;
- X int j;
- X
- X stringset_args = *args;
- X stringset_pos = 1;
- X stringset_lex();
- X
- X wl_zero(&wl);
- X if (stringset_one(&wl))
- X return -1;
- X for (j = 0; j < wl.wl_nwords; ++j)
- X wl_append(result, wl.wl_word[j]);
- X wl_free(&wl);
- X return 0;
- X}
- X
- X
- X/*
- X * NAME
- X * func_quote - quote the arguments
- X *
- X * SYNOPSIS
- X * int func_quote(wlist *result, wlist *args);
- X *
- X * DESCRIPTION
- X * The quote function is a built-in of cook, described as follows:
- X * This function requires one or more arguments.
- X *
- X * RETURNS
- X * A word list containing the values of the arguments
- X * surrounded by double quotes.
- X *
- X * CAVEAT
- X * The returned result is in dynamic memory.
- X * It is the responsibility of the caller to dispose of
- X * the result when it is finished, with a wl_free() call.
- X */
- X
- Xstatic int func_quote _((wlist *, wlist *));
- X
- Xstatic int
- Xfunc_quote(result, args)
- X wlist *result;
- X wlist *args;
- X{
- X int j;
- X static char *tmp;
- X static size_t tmp_len;
- X size_t len;
- X char *cp1;
- X char *cp2;
- X char *cp3;
- X string_ty *s;
- X static char special[] = "\bb\ff\nn\rr\tt";
- X
- X assert(result);
- X assert(args);
- X assert(args->wl_nwords);
- X for (j = 1; j < args->wl_nwords; ++j)
- X {
- X len = 2;
- X for (cp1 = args->wl_word[j]->str_text; *cp1; ++cp1)
- X {
- X if (*cp1 < ' ' || *cp1 > '~')
- X {
- X if (strchr(special, *cp1))
- X len += 2;
- X else
- X len += 4;
- X }
- X else
- X {
- X if (strchr("\"\\", *cp1))
- X ++len;
- X ++len;
- X }
- X }
- X if (len > tmp_len)
- X {
- X tmp_len = len;
- X if (!tmp)
- X tmp = mem_alloc(tmp_len);
- X else
- X mem_change_size(&tmp, tmp_len);
- X }
- X cp2 = tmp;
- X *cp2++ = '"';
- X for (cp1 = args->wl_word[j]->str_text; *cp1; ++cp1)
- X {
- X if (*cp1 < ' ' || *cp1 > '~')
- X {
- X cp3 = strchr(special, *cp1);
- X if (cp3)
- X {
- X *cp2++ = '\\';
- X *cp2++= cp3[1];
- X }
- X else
- X {
- X *cp2++ = '\\';
- X *cp2++ = '0' + ((*cp1 >> 6) & 3);
- X *cp2++ = '0' + ((*cp1 >> 3) & 7);
- X *cp2++ = '0' + (*cp1 & 7);
- X }
- X }
- X else
- X {
- X if (strchr("\"\\", *cp1))
- X *cp2++ = '\\';
- X *cp2++ = *cp1;
- X }
- X }
- X *cp2 = '"';
- X s = str_n_from_c(tmp, len);
- X wl_append(result, s);
- X str_free(s);
- X }
- X return 0;
- X}
- X
- X
- X/*
- X * NAME
- X * func_uptodate - test if files are up to date
- X *
- X * SYNOPSIS
- X * int func_uptodate(wlist *result, wlist *args);
- X *
- X * DESCRIPTION
- X * The uptodate function is a built-in of cook, described as follows:
- X * returns true if all the arguments are up-to-date.
- X * Does not build them if they are not.
- X * This function requires one or more arguments.
- X *
- X * RETURNS
- X * A word list containing true ("1") if all arguments are up-to-date,
- X * or false ("") if one or more could not.
- X *
- X * CAVEAT
- X * The returned result is in dynamic memory.
- X * It is the responsibility of the caller to dispose of
- X * the result when it is finished, with a wl_free() call.
- X */
- X
- Xstatic int func_uptodate _((wlist *, wlist *));
- X
- Xstatic int
- Xfunc_uptodate(result, args)
- X wlist *result;
- X wlist *args;
- X{
- X int j;
- X int ret;
- X
- X assert(result);
- X assert(args);
- X assert(args->wl_nwords);
- X for (j = 1; j < args->wl_nwords; ++j)
- X {
- X ret = isit_uptodate(args->wl_word[j]);
- X if (ret < 0)
- X return -1;
- X if (!ret)
- X {
- X wl_append(result, str_false);
- X return 0;
- X }
- X }
- X wl_append(result, str_true);
- X return 0;
- X}
- X
- X
- X/*
- X * NAME
- X * func_cando - test if know how to cook given files
- X *
- X * SYNOPSIS
- X * int func_cando(wlist *result, wlist *args);
- X *
- X * DESCRIPTION
- X * The cando function is a built-in of cook, described as follows:
- X * returns true if all the arguments are known how to be cooked.
- X * This function requires one or more arguments.
- X *
- X * RETURNS
- X * A word list containing true ("1") if can do all arguments,
- X * or false ("") if one or more could not.
- X *
- X * CAVEAT
- X * The returned result is in dynamic memory.
- X * It is the responsibility of the caller to dispose of
- X * the result when it is finished, with a wl_free() call.
- X */
- X
- Xstatic int func_cando _((wlist *, wlist *));
- X
- Xstatic int
- Xfunc_cando(result, args)
- X wlist *result;
- X wlist *args;
- X{
- X int j;
- X int ret;
- X
- X assert(result);
- X assert(args);
- X assert(args->wl_nwords);
- X for (j = 1; j < args->wl_nwords; ++j)
- X {
- X ret = cando(args->wl_word[j]);
- X if (!ret)
- X {
- X wl_append(result, str_false);
- X return 0;
- X }
- X }
- X wl_append(result, str_true);
- X return 0;
- X}
- X
- X
- X/*
- X * NAME
- X * func_sort - sort the arguments
- X *
- X * SYNOPSIS
- X * int func_sort(wlist *result, wlist *args);
- X *
- X * DESCRIPTION
- X * The func_sort function is a built-in of cook, described as follows:
- X * sorts the arguments lexicagraphically.
- X * This function requires zero or more arguments.
- X *
- X * RETURNS
- X * A sorted word list.
- X *
- X * CAVEAT
- X * The returned result is in dynamic memory.
- X * It is the responsibility of the caller to dispose of
- X * the result when it is finished, with a wl_free() call.
- X */
- X
- Xstatic int func_sort_cmp _((const void *, const void *));
- X
- Xstatic int
- Xfunc_sort_cmp(va, vb)
- X const void *va;
- X const void *vb;
- X{
- X string_ty *a;
- X string_ty *b;
- X
- X a = *(string_ty **)va;
- X b = *(string_ty **)vb;
- X return strcmp(a->str_text, b->str_text);
- X}
- X
- X
- Xstatic int func_sort _((wlist *, wlist *));
- X
- Xstatic int
- Xfunc_sort(result, args)
- X wlist *result;
- X wlist *args;
- X{
- X int j;
- X int start;
- X
- X assert(result);
- X assert(args);
- X switch (args->wl_nwords)
- X {
- X case 0:
- X assert(0);
- X
- X case 1:
- X return 0;
- X
- X case 2:
- X wl_append(result, args->wl_word[1]);
- X return 0;
- X }
- X start = result->wl_nwords;
- X for (j = 1; j < args->wl_nwords; ++j)
- X wl_append(result, args->wl_word[j]);
- X qsort
- X (
- X &result->wl_word[start],
- X args->wl_nwords - 1,
- X sizeof(result->wl_word[0]),
- X func_sort_cmp
- X );
- X return 0;
- X}
- X
- X
- X/*
- X * NAME
- X * func - table of built-in functions
- X *
- X * SYNOPSIS
- X * func_ty func[];
- X *
- X * DESCRIPTION
- X * Func is a table of function names and pointers
- X * for the built-in functions of cook.
- X */
- X
- Xstatic func_ty func[] =
- X{
- X { "and", func_and, },
- X { "cando", func_cando, },
- X { "catenate", func_catenate, },
- X { "collect", func_collect, },
- X { "collect_lines", func_collect, },
- X { "count", func_count, },
- X { "defined", func_defined, },
- X { "dir", func_dir, },
- X { "dirname", func_dir, },
- X { "downcase", func_downcase, },
- X { "entryname", func_entryname, },
- X { "execute", func_exec, },
- X { "exists", func_mtime, },
- X { "find_command", func_find_command, },
- X { "fromto", func_fromto, },
- X { "getenv", func_getenv, },
- X { "glob", glob, },
- X { "head", func_head, },
- X { "if", func_if, },
- X { "in", func_in, },
- X { "match", func_match, },
- X { "matches", func_match, },
- X { "match_mask", func_match_mask, },
- X { "mtime", func_mtime, },
- X { "not", func_not, },
- X { "operating_system", func_opsys, },
- X { "os", func_opsys, },
- X { "or", func_or, },
- X { "pathname", func_pathname, },
- X { "prepost", func_prepost, },
- X { "quote", func_quote, },
- X { "resolve", cook_mtime_resolve, },
- X { "sort", func_sort, },
- X { "stringset", stringset, },
- X { "tail", func_tail, },
- X { "upcase", func_upcase, },
- X { "uptodate", func_uptodate, },
- X};
- X
- X
- X/*
- X * NAME
- X * builtin_initialize - start up builtins
- X *
- X * SYNOPSIS
- X * void builtin_initialize(void);
- X *
- X * DESCRIPTION
- X * The builtin_initialize function is used to initialize the symbol table
- X * with the names and pointers to the builtin functions.
- X *
- X * CAVEAT
- X * This function must be called after the id_initialize function.
- X */
- X
- Xvoid
- Xbuiltin_initialize()
- X{
- X func_ty *fp;
- X string_ty *s;
- X
- X for (fp = func; fp < ENDOF(func); ++fp)
- X {
- X s = str_from_c(fp->f_name);
- X id_assign(s, ID_CLASS_BUILTIN, fp->f_code);
- X str_free(s);
- X }
- X}
- END_OF_FILE
- if test 43130 -ne `wc -c <'cook/builtin.c'`; then
- echo shar: \"'cook/builtin.c'\" unpacked with wrong size!
- fi
- # end of 'cook/builtin.c'
- fi
- echo shar: End of archive 11 \(of 11\).
- cp /dev/null ark11isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 11 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-